Developing code for software today is typically an iterative process. For example, a programmer writes code to realize a software application, compiles and runs the code to test for problems, and then oftentimes rewrites the code to add on functionality and address defects and/or problems discovered during testing. As part of the testing and/or debugging process, the programmer can launch tools to help the programmer to debug the code while it is executing. In some cases, the tools can expose local variables and values associated with a function, set breakpoints in the code to temporarily halt execution, as well as display a call stack trace and enable memory dumps. These features of the tools help the programmer to track variables as their values change, stop code execution at points of interest to examine the state of the code, see a progression of function calls, such as which functions call other functions, and the like.
One deviation from this, however, is an inline function. Inline functions are functions that a compiler expands inline at compile time. When expanding the inline function, the compiler inserts instructions executing the complete body of the function, instead of generating instructions that reference a function pointer to the inline function. Consequently, information pertaining to the inline function can be lost when it gets expanded, thus translating into a reduced ability to debug around the inline functions. Optimized code can further compound this problem, since the compiler may reorganize instructions to suit selected optimizations and cause the debugging tool and the executing code to be out of synchrony.